home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chaos CD Blue
/
Chaos_CD_Blue__[1999].iso
/
contrib
/
software
/
bbpc
/
pcm.c
< prev
next >
Wrap
Text File
|
1998-04-27
|
7KB
|
271 lines
/* compact memory model */
#include <stdio.h>
#include <io.h>
#include <dos.h>
#include <fcntl.h>
#include <math.h>
#include <alloc.h>
#include <stdlib.h>
#include <string.h>
#define PI 3.14159265358979323
#define TIMER0CLOCK 1193182L /* Grundfreqenz des Timerbausteins */
#define TIMER0DIV 70 /* divisor für timer 0 : sample time=30/CLOCK_FREQ = 25.1 uSec */
FILE *fpspeich; /* zur sofortigen speicherung des PCM-files */
int portadr; /* printer port adresse */
#define MAXARRAY 65000 /* maximale an Bytes im abspielfeld */
#define MAXFIELDS 4 /* anzahl an abspielfeldern */
long anzahl; /* anzahl im momentanen abspielfeld */
long anzahlfeld[MAXFIELDS]; /* anzahl von zeichen die noch zu spielen sind (pro abspielfeld)*/
char *memadr[MAXFIELDS]; /* zeiger auf alle die apspielfelder */
long tmpanzahlfeld[MAXFIELDS]; /* feld um nur einzelne Stuecke abzuspielen */
char *tmpmemadr[MAXFIELDS]; /* feld um nur einzelne Stuecke abzuspielen */
char *memadr2; /* zeiger auf das naechste anzuspielende byte */
void interrupt (*old_vec)(); /* Adresse der alten Timerseviceroutine */
void interrupt tic_once(); /* prototyp der abspielroutine */
void
wave(f1, f2, tone)
unsigned int f1, f2; /* zwei freqenzen die sich ueberlagern */
unsigned int tone; /* dauer in mSekunden */
{
double dt, dauer;
double freqtime;
dt = (double)TIMER0DIV/(double)TIMER0CLOCK; /* dauer eines abtastzeitpunktes */
dauer = (double)tone/(double)1000;
for (freqtime = 0; freqtime < dauer; freqtime += dt) {
if (f1 == 0 && f2 == 0) tone = 0x80;
else tone = 64 * (2 + (sin(2*PI*freqtime*f1) + sin (2*PI*freqtime*f2)));
if (tone >= 256) tone = 255;
if (tone < 0) tone = 0;
fputc(tone, fpspeich);
}
}
void
playtone()
{
int i;
char old_0x21;
disable(); /* alle interrupts abschalten */
old_vec = getvect(0x08); /* alte Timerserviceroutine retten */
setvect(0x08, tic_once); /* timerserviceroutine auf ton abspielen setzen */
outportb(0x43, 0x14); /* setzen der neuen abtastgeschwindigkeit */
outportb(0x40, TIMER0DIV);
old_0x21 = inportb(0x21); /* interrupt maske holen */
outportb(0x21, 0xFE); /* nur Timer 0 einschalten */
enable(); /* jetzt gehts los */
for (i = 0; i < MAXFIELDS; i++) { /* alle abspielfelder abspielen */
anzahl = tmpanzahlfeld[i];
memadr2 = tmpmemadr[i];
while (anzahl > 0L) ; /* warten bis alles ausgesendet wurde */
}
disable(); /* wieder keine Interrupts */
outportb(0x21, old_0x21); /* alte interrupt maske restaurieren */
outportb(0x43, 0x34); /* Timer0 wieder auf uebliche Zeitbasis (18.2Sekunden stellen */
outportb(0x40, 0x68);
outportb(0x40, 0xFF);
setvect(0x08, old_vec); /* alte timerserviceroutine wiederherstellen */
enable(); /* nun wieder normales don mit normalen interrupts */
}
void interrupt tic_once()
{
outportb(portadr, *memadr2); /* ausgabe des neuen pcm-wertes */
memadr2++;
anzahl--; /* anzahl verringern */
outportb(0x20,0x20); /* end of interrupt klarmachen */
}
void readpcm(str)
char *str;
{
int i;
FILE *fp;
fp = fopen(str, "rb");
if (fp != NULL) {
for (i = 0; i < MAXFIELDS; i++) {
if (anzahlfeld[i] == 0L) { /* leeres Feld also File einlesen */
while (anzahlfeld[i] < MAXARRAY && !feof(fp)) {
memadr[i][anzahlfeld[i]] = fgetc(fp);
anzahlfeld[i]++;
};
}
}
fclose(fp);
}
}
void playfields()
{
int i, j;
printf("-\nPCM-Playmodus...bitte File auswaehlen\n\n");
j = 0;
for (i = 0; i < MAXFIELDS; i++) {
if (anzahlfeld[i] > 0L && (anzahlfeld[i] < MAXARRAY || j == 0)) {
printf("File:%d\n", i+1);
j = 0;
}
if (anzahlfeld[i] >= MAXARRAY) j = 1;
}
printf("Q = Quit\n");
do {
for (i = 0; i < MAXFIELDS; i++) { /* tmpfeld zuruecksetzen */
tmpanzahlfeld[i] = 0L;
tmpmemadr[i] = memadr[i];
}
while(bioskey(1) == 0);
i = bioskey(0); /* taste einlesen */
if ((char)i == 'Q' || (char)i == 'q') return;
i = (char)i-49;
if (i < 0) i = 0;
if (i >= MAXFIELDS) i = MAXFIELDS-1;
do { /* nur das abzuspielende Feld einblenden */
tmpanzahlfeld[i] = anzahlfeld[i];
if (anzahlfeld[i] < MAXARRAY) break;
i++;
} while (i < MAXFIELDS);
printf("playing... %d\r",i+1);
fflush(stdout);
playtone(); /* Feld abspielen */
printf(" \r");
fflush(stdout);
} while (42);
}
void main(argc, argv)
int argc;
char *argv[];
{
char fstr2[80], fstr3[80];
char playfile[MAXFIELDS][80];
char string[80];
unsigned long anz;
FILE *fp;
int n, l, s, m, i, j, k;
n = l = s = m = 0;
portadr = 0x378;
if (argc <= 1) {
printf("PCM-Soundprogramm (c) 1991 bei Hacko\n\n");
printf("-1 oder -2 oder -3 um dem Printerport festzulegen\n");
printf("-sX = schreiben PCM-File, wobei X der Name der Datei ist\n");
printf("-lX = lesen PCM-File, wobei X der Name der Dabei ist\n");
printf("-mX = Makrodatei auswerten und berechnen, wobei X der Name der Datei ist\n");
printf(" in jeder Zeile der Makrodatei steht 'f1 f2 t' wobei:\n");
printf(" f1 = Frequenz Nummer1\n");
printf(" f2 = Frequenz Nummer2\n");
printf(" t = Dauer in m Sekunden\n");
printf("-n = keinen Sound ausgeben (nur Sound berechnen)\n");
exit(0);
}
for (i = 0; i < MAXFIELDS; i++) { /* spielfiles init */
playfile[i][0] = '\0';
}
for (i = 1; i < argc; i++) { /* komandozeilen auswertung */
if (argv[i][0] == '-') {
if (argv[i][1] == '2') {
portadr = 0x278;
}
if (argv[i][1] == '3') {
portadr = 0x3BC;
}
if (argv[i][1] == 'n') {
n = 1;
}
if (argv[i][1] == 'l') {
if (l+1 <= MAXFIELDS) {
strcpy(playfile[l], &argv[i][2]);
l++;
}
}
if (argv[i][1] == 's') {
s = 1;
strcpy(fstr2, &argv[i][2]);
}
if (argv[i][1] == 'm') {
m = 1;
strcpy(fstr3, &argv[i][2]);
}
}
}
if ((l >= 1 && s == 1) || (l == 0 && m == 0)) {
exit(0);
}
if (m == 1) { /* makrofile lesen */
fp = fopen(fstr3, "r");
if (s == 1) {
fpspeich = fopen(fstr2, "wb");
} else {
fpspeich = fopen("tmp.pcm", "wb");
}
printf("PCM-Berechnungsmodus...bitte warten\n");
if (fp != NULL && fpspeich != NULL) {
memadr2 = memadr;
do {
i = j = k = 0;
fscanf(fp, "%d %d %d\n", &i, &j, &k);
printf("freq1=%d Hz / freq2=%d Hz / timing=%d ms \r", i, j, k);
fflush(stdout);
wave(i, j, k);
} while(!feof(fp));
fclose(fp);
fclose(fpspeich);
}
printf("Berechnung beendet. \n");
}
if (n == 0) { /* abspielen der tonfolge */
if (l >= 1) ;
else if (s == 1) strcpy(playfile[0], fstr2);
else strcpy(playfile[0], "tmp.pcm");
for (i = 0; i < MAXFIELDS; i++) { /* felder init */
memadr[i] = malloc(MAXARRAY);
if (memadr[i] == NULL) {
printf("kein Speicher mehr da");
exit(0);
}
anzahlfeld[i] = 0L;
}
for (i = 0; i < MAXFIELDS; i++) { /* files einlesen */
if (strlen(playfile[i]) >= 1) readpcm(playfile[i]);
}
playfields();
for (i = 0; i < MAXFIELDS; i++) { /* felder wieder los werden */
free(memadr[i]);
}
}
}